﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ForumReader
{
    /// <summary>
    /// Provides the interface of a client that reads a forum.
    /// </summary>
    public interface ForumClient
    {
        /// <summary>
        /// Gets the display name of the forum.
        /// </summary>
        string ForumTitle { get; }

        /// <summary>
        /// Retrieves the boards in the forum. The boards are returned in
        /// chunks to optimize network performance and provide caching hints.
        /// </summary>
        /// <param name="ct">Token to cancel the operation.</param>
        /// <exception cref="OperationCanceledException">If the operation
        /// is cancelled before completion.</exception>
        /// <returns>An iterator that returns the boards in chunks.</returns>
        IEnumerable<ForumBoard[]> GetBoards(CancellationToken ct);

        /// <summary>
        /// Retrieves the threads in the given board. The posts are returned in
        /// chunks to optimize network performance and provide caching hints.
        /// </summary>
        /// <param name="boardId">Id of the board whose threads to retrieve.</param>
        /// <param name="ct">Token to cancel the operation.</param>
        /// <exception cref="OperationCanceledException">If the operation
        /// is cancelled before completion.</exception>
        /// <returns>An iterator that returns the threads in chunks.</returns>
        IEnumerable<ForumThread[]> GetThreads(string boardId, CancellationToken ct);

        /// <summary>
        /// Retrieves the posts in the given thread. The posts are returned in
        /// chunks to optimize network performance and provide caching hints.
        /// </summary>
        /// <param name="threadId">Id of the thread whose posts to retrieve.</param>
        /// <param name="ct">Token to cancel the operation.</param>
        /// <exception cref="OperationCanceledException">If the operation
        /// is cancelled before completion.</exception>
        /// <returns>An iterator that returns the posts in chunks.</returns>
        IEnumerable<ForumPost[]> GetPosts(string threadId, CancellationToken ct);
    }

    /// <summary>
    /// Represents a forum board.
    /// </summary>
    public class ForumBoard
    {
        /// <summary>
        /// Gets or sets the id of the board, which is used to uniquely
        /// identify this board within the forum.
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// Gets or sets the name of the board.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets the title of the board.
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// Gets or sets the number of threads currently in the board.
        /// </summary>
        public int ThreadCount { get; set; }
    }
    
    /// <summary>
    /// Represents a forum thread.
    /// </summary>
    public class ForumThread
    {
        /// <summary>
        /// Gets an id that uniquely identifies this thread within the forum.
        /// </summary>
        public string Id;

        /// <summary>
        /// Gets the title of the thread.
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// Gets the date of the thread.
        /// </summary>
        public DateTime Date { get; set; }

        /// <summary>
        /// Gets an URL from which to view this thread in a browser.
        /// </summary>
        public string Link { get; set; }
    }

    /// <summary>
    /// Represents a forum post.
    /// </summary>
    public class ForumPost
    {
        public string Author { get; set; }
        public DateTime Date { get; set; }
        public ForumAttachment[] Attachments { get; set; }
        //public string[] Images { get; set; }
        //public string[] Videos { get; set; }
    }

    /// <summary>
    /// Represents an attachment in a forum post.
    /// </summary>
    public class ForumAttachment
    {
        /// <summary>
        /// Gets the type of the attachment.
        /// </summary>
        public ForumAttachmentType Type { get; set; }

        /// <summary>
        /// Gets the source URL of the attachment.
        /// </summary>
        public string Source { get; set; }

        /// <summary>
        /// Gets the URL of the thumbnail of the attachment.
        /// </summary>
        public string Thumbnail { get; set; }

        /// <summary>
        /// Gets or sets the loaded attachment.
        /// </summary>
        public object Object;

        /// <summary>
        /// Gets or sets the size of the attachment in bytes.
        /// </summary>
        public int Size;
    }

    public enum ForumAttachmentType
    {
        General = 0,
        Image = 1,
        Video = 2,
        Audio = 3,
    }

    //public class ForumCategory
    //{
    //}
}
